import {Injectable} from '@angular/core';
import {AbstractClassPart} from '@angular/compiler/src/output/output_ast';
import {RequestClientService} from './request-client.service';
import {User} from './user';


import {Observable} from 'rxjs';
import {Observer} from 'rxjs';
import {Subject} from 'rxjs';
import {of} from 'rxjs';

declare let window: any;

@Injectable()
export class NormalService extends RequestClientService {

    public DataPool: any = {};
    public lang: any;

    public news$: Observable<any>;
    public user$: any;
    public logout$: any;

    private newsObserver: Observer<any>;
    private userSubject: Subject<any> = new Subject<any>();
    private logoutObserver: Observer<boolean>;

    public usersService: any;
    public transactionsService: any;

    private usersupdateService: any;
    private uploadsService: any;

    public News: any;

    constructor() {
        super();
        this.lang = this.language;
        // 配置语言信息

        this.usersService = this.client.service('users');

        this.News = this.client.service('news');
        this.transactionsService = this.client.service('transactions');
        this.news$ = new Observable(observer => this.newsObserver = observer);

        this.logout$ = new Observable(observer => this.logoutObserver = observer);
        if (this.isLogin()) {
            this.getAuthPromise();
        }
        this.user$ = this.userSubject.asObservable();

        this.client.service('mailer').timeout = 30000;
        this.client.service('paypassword').timeout = 30000;


    }

    getnews(): void {
        this.News.find().then(news => {

        });
    }

    getAuthPromise(): void {
        this.authPromise = this.client.authenticate();

        return this.authPromise.then(suc => {
            // 认证通过后初始化其他授权服务
            this.usersupdateService = this.client.service('usersupdate');
            window.usersupdateService = this.usersupdateService;
            this.uploadsService = this.client.service('uploads');
        }).catch(e => {
            if (e.code ==401) 
            this.loginOut();
        });
    }

    async getuser(): Promise<any> {
        if (!this.isLogin()) return;
        return this.authPromise.then(suc => {
            this.DataPool.user = suc.user;
            this.userSubject.next(this.DataPool.user);
        }, error => {
            throw error;
        });
    }

    finduser(query): void {

    }

    async updateuser(id, data, params = {}): Promise<any> {
        try {
            this.getAuthPromise();
            let suc = await this.authPromise;
            let newUser = await this.usersService.update(id, data, params);
            if (newUser) {
                this.DataPool.user = newUser;
                this.userSubject.next(this.DataPool.user);
                return newUser;
            }
        } catch (e) {
            if (e.code == 401) 
            this.loginOut();
            throw e;
        }
    }

    async updatepassword(id, data): Promise<any> {
        this.getAuthPromise();
        return this.authPromise.then(suc => {
            return this.usersupdateService.update(id, data, {}).then(userId => {
                return userId;
            }).catch(e => {
                throw e;
            });
        });
    }

    async transforToken(data): Promise<any> {

        try {
            // let suc = await this.authPromise;
            let user = await this.usersupdateService.create(data);
            this.DataPool.user = user;
            this.userSubject.next(this.DataPool.user);
            window.location = '/#/account/transferHistory';
            return user;

        }
        catch (e) {
            throw e;
        }

    }

    loginOut(): void {
        //delete this.storage[this.storageKey];
        this.client.logout();
        this.logoutObserver.next(true);
        window.location.reload();
    }

    async login(model: User, code: string) {
        return this.client.authenticate({
            strategy: 'local',
            email: model.email,
            password: model.password,
            code: code
        }).then((user) => {
            this.storage.setItem(this.storageKey, user.accessToken);
            this.DataPool.user = user.user;
            this.userSubject.next(this.DataPool.user);
            this.getAuthPromise();
            return true;
        }).catch((error) => {
            if(error.code==401)
            this.loginOut();
            throw error;
        });
    }

    async signUp(model: User): Promise<any> {
        return this.usersService.create(model).then((result) => {
            return result;
        }).catch((error) => {
            throw error;
        });
    }

    async getVerify(email: string): Promise<any> {

        return this.client.service('mailer').find({query: {email: email}}).then((result) => {
            return result;
        }).catch((error) => {
            throw error;
        });
    }

    async checkPassword(model: User): Promise<any> {
        try {
            let user = await this.client.authenticate({
                strategy: 'local',
                email: model.email,
                password: model.password
            });
            console.log('checkPassword', model);
            return user;
        }
        catch (e) {
            throw e;
        }
    }

    async checkVerify(email: string, code: string): Promise<any> {
        return this.client.service('mailer').get(code, {query: {email: email, code: code}}).then((result) => {
            return result;
        }).catch((error) => {
            throw error;
        });
    }

    async getCaptchaImg(data: any): Promise<any> {
        return this.client.service('mailer').create(data).then(result => {
            return result;
        }).catch(error => {
            throw error;
        });
    }

    async checkCaptcha(id: string, code: string): Promise<any> {
        return this.client.service('mailer').update(id, {value: code}).then(result => {
            return result;
        }).catch(error => {
            throw error;
        });
    }

    private handleError<T>(operation = 'operation', result?: T) {
        return (error: any): Observable<T> => {

            // TODO: send the error to remote logging infrastructure
            console.error(error); // log to console instead

            // TODO: better job of transforming error for user consumption
            console.log(`${operation} failed: ${error.message}`);

            // Let the app keep running by returning an empty result.
            return of(result as T);
        };
    }

    async forgetPassword(email: string, lang: string): Promise<any> {
        return this.client.service('paypassword').find({query: {email: email, lang: lang}}).then(result => {
            console.log('normal result', result);
            return result;
        }).catch(error => {
            throw error;
        });
    }

    async forgetPayPassword(id: string, email: string): Promise<any> {
        return this.client.service('paypassword').get(id, {
            query: {email: email}
        });
    }

    async findTransfer(params): Promise<any> {
        this.getAuthPromise();
        let suc = await this.authPromise;
        let transfers = await this.transactionsService.find(params);
        return transfers;
    }

    async createPayPassword(password: string, payPassword: string): Promise<any> {
        return this.client.service('paypassword').create({password: password, paypassword: payPassword});
    }

    async updatePayPassword(id: string, oldPass: string, newPass: string): Promise<any> {
        this.getAuthPromise();
        return this.client.service('paypassword').update(id, {paypasswordold: oldPass, paypasswordnew: newPass});
    }

    async submitPassword(email: string, password: string, changecode: string): Promise<any> {
        this.getAuthPromise();
        return this.client.service('paypassword').patch(email, {password: password, changeCode: changecode});
    }


    setLang(type) {
        this.lang = this.setLangMessage({type: type});
    }

}